<template>
	<view>
		<canvas canvas-id="first" disable-scroll @touchstart="start" @touchmove="move" @touchend="end"
			class="rounded-50r box-shadow" style="width: 100%;height: 750rpx; background-color: #fff;"></canvas>

	</view>
</template>

<script>
	import dragGraph from '@/components/wy-canvas/dragGraph.js'
	export default {
		name: "wy-canvas",
		data() {
			return {
				ctx: null,
				drawArr: [],
				height: 750,
				width: 750,
				tempGraphArr: [],
				currentGraph: {},
				currentTouch: {},
				lineData: [],
				maxX: 0,
				maxY: 0,
				minX: 750,
				minY: 750
				// bgImage:''
			};
		},
		created() {

		},
		mounted() {

			
			// console.log(this.bgImage);
			const sysInfo = uni.getSystemInfoSync();
			const screenWidth = sysInfo.screenWidth;
			this.factor = screenWidth / 750;

			this.ctx = uni.createCanvasContext('first', this);
			// console.log(this.bgImage);
			this.draw();
		},
		props: {
			graph: {
				type: Object
			},

			bgColor: {
				type: String,
				default: 'red'
			},

			bgImage: {
				type: String,
				default: ''
			},
			mode: {
				type: String,
				default: ''
			},
			// 画笔大小，权重小于penLineWidth
			lineWidth: {
				type: Number,
				default: 10
			},
			// 线颜色，权重小于penLineColor
			lineColor: {
				type: String,
				default: '#333'
			},
			lineStyle: {
				type: String,
				default: 'round'
			},
			mode: {
				type: String,
				default: 'graph'
			}
		},
		watch: {
			graph: {
				//监听图改变的事件
				handler(n, o) {
					if (JSON.stringify(n) === '{}') return;

					this.drawArr.push(new dragGraph(Object.assign({
						x: 100, //默认x，y是30，传n进入可以改变x，y
						y: 100,
					}, n), this.ctx, this.factor));
					// console.log(this.drawArr);
					this.draw(); //每次图变化就把画布背景以及所有绘图元素重新绘制到画布上

				}
			},
			bgImage:{
				handler(n, o) {
					
					this.draw(); 
				
				}
			}
		},
		methods: {
			toPx(rpx) {
				return rpx * this.factor;
			},
			draw() {
				this.ctx.save()
				if (this.bgImage !== '') {
					this.ctx.drawImage(this.bgImage, 0, 0, this.toPx(this.width), this.toPx(this.height));
				}
				// this.ctx.globalCompositeOperation='source-out';

				// this.ctx.setStrokeStyle('red')
				// this.ctx.strokeRect(75, 40, 225, 330)
				// this.ctx.rect(75, 40, 225, 300)
				// this.ctx.stroke();
				// this.ctx.setFillStyle('rgba(1,0,0,0.1)')
				// this.ctx.fill()

				// this.ctx.restore()

				// if (this.bgColor !== '') {
				// 	this.ctx.save();
				// 	this.ctx.setFillStyle(this.bgColor);
				// 	this.ctx.fillRect(0, 0, this.toPx(this.width), this.toPx(this.height));
				this.ctx.restore();

				// }
				this.drawArr.forEach((item) => {
					item.paint();
				});
				return new Promise((resolve) => {
					this.ctx.draw(false, () => {
						resolve();
					});
				});
			},
			start(e) {
				if (this.mode === 'graph') {
					this.startGraph(e);
				} else {
					console.log('choose line');
					this.startLine(e);
				}
			},
			move(e) {
				if (this.mode === 'graph') {
					this.moveGraph(e);
				} else {
					this.moveLine(e);
				}
			},
			end(e) {
				if (this.mode === 'graph') {
					this.endGraph(e);
				} else {
					this.endLine(e);
				}
			},
			startGraph(e) {
				const {
					x,
					y
				} = e.touches[0];
				this.tempGraphArr = [];
				this.drawArr && this.drawArr.forEach((item, index) => {
					// item.selected = false;
					const action = item.isInGraph(x, y);
					if (action) {
						if (action === 'del' && item.selected) {
							this.drawArr.splice(index, 1);
							this.ctx.clearRect(0, 0, this.toPx(this.width), this.toPx(this.height));
							this.ctx.draw();
						} else if (action === 'transform' || action === 'move') {
							item.action = action;
							this.tempGraphArr.push(item);
							if(item.type == 'text'){
								this.$emit('textSelect',index)
							}
							// 保存点击时的坐标
							this.currentTouch = {
								x,
								y
							};
						}
						
					} else {
						item.selected = false;
						
					}
				});
				// 保存点击时元素的信息
				if (this.tempGraphArr.length > 0) {
					const lastIndex = this.tempGraphArr.length - 1;
					this.tempGraphArr[lastIndex].selected = true;
					this.currentGraph = Object.assign({}, this.tempGraphArr[lastIndex]);
				}
				this.draw();
			},
			startLine(e) {
				const pos = e.touches[0]
				this.minX = pos.x < this.minX ? pos.x : this.minX;
				this.minY = pos.y < this.minY ? pos.y : this.minY;
				this.lineData.push({
					style: {
						color: this.lineColor,
						width: this.lineWidth
					},
					// 屏幕坐标
					coordinates: [{
						type: e.type,
						x: pos.x,
						y: pos.y
					}]
				})
				this.drawLine()
			},
			moveGraph(e) {
				const {
					x,
					y
				} = e.touches[0];
				if (this.tempGraphArr && this.tempGraphArr.length > 0) {
					const currentGraph = this.tempGraphArr[this.tempGraphArr.length - 1];
					if (currentGraph.action === 'move') {
						currentGraph.x = this.currentGraph.x + (x - this.currentTouch.x);
						currentGraph.y = this.currentGraph.y + (y - this.currentTouch.y);
					} else if (currentGraph.action === 'transform') {
						currentGraph.transform(this.currentTouch.x, this.currentTouch.y, x, y, this.currentGraph);
					}
					vk.pubfn.throttle(this.draw, 20, true)
					// this.draw();
				}
			},
			moveLine(e) {
				const pos = e.touches[0]
				this.maxX = pos.x > this.maxX ? pos.x : this.maxX;
				this.maxY = pos.y > this.maxY ? pos.y : this.maxY;
				this.minX = pos.x < this.minX ? pos.x : this.minX;
				this.minY = pos.y < this.minY ? pos.y : this.minY;
				this.lineData[this.lineData.length - 1].coordinates.push({
					type: e.type,
					x: pos.x,
					y: pos.y
				})
				this.drawLine()
			},
			endGraph(e) {
				this.tempGraphArr = [];
			},
			endLine(e) {
				this.ctx.save()
				const width = this.maxX - this.minX;
				const height = this.maxY - this.minY;
				this.ctx.rect(this.minX, this.minY, width, height)
				this.ctx.setFillStyle('red')
				this.ctx.stroke()

				this.ctx.draw(true)
				this.ctx.restore();
				this.maxX = 0;
				this.maxY = 0;
				this.minX = 750;
				this.minY = 750;
			},
			rePaintLine() {
				this.draw();
				const lineDataLen = this.lineData.length
				if (!lineDataLen) return
				const currentLineData = this.lineData[lineDataLen - 1]
				const coordinates = currentLineData.coordinates
				const coordinatesLen = coordinates.length
				for (let i = 1; i <= coordinatesLen; i++) {
					let startPos
					let endPos
					// let centerPos
					if (i < 2) {
						// only start, no move event
						startPos = coordinates[i - 1]
						// centerPos = {
						// 	x: startPos.x + 0.5,
						// 	y: startPos.y
						// }
						endPos = {
							x: startPos.x + 1,
							y: startPos.y
						}
					} else {
						startPos = coordinates[i - 2]
						// centerPos = coordinates[coordinatesLen - 1]
						endPos = coordinates[i - 1]
					}
					const style = currentLineData.style
					this.ctx.save()
					this.ctx.scale(2, 2)
					this.ctx.beginPath()
					this.ctx.setLineCap('round')
					// this.ctx.shadowBlur = 10;
					// this.ctx.shadowColor = 'rgb(0, 0, 0)';
					this.ctx.setGlobalAlpha(0.5)
					this.ctx.setStrokeStyle(style.color)
					this.ctx.setLineWidth(style.width)
					this.ctx.moveTo(startPos.x, startPos.y)
					this.ctx.lineTo(endPos.x, endPos.y)
					// const P1 = this.caculateBezier(startPos, endPos, centerPos)
					// this.ctx.moveTo(startPos.x, startPos.y)
					// this.ctx.quadraticCurveTo(P1.x, P1.y, endPos.x, endPos.y)
					this.ctx.stroke()
					this.ctx.restore();
					this.ctx.draw(true)
				}
			},
			// 绘制线条
			drawLine() {
				const lineDataLen = this.lineData.length
				if (!lineDataLen) return
				const currentLineData = this.lineData[lineDataLen - 1]
				const coordinates = currentLineData.coordinates
				const coordinatesLen = coordinates.length
				if (!coordinatesLen) return
				let startPos
				let endPos
				// let centerPos
				if (coordinatesLen < 2) {
					// only start, no move event
					startPos = coordinates[coordinatesLen - 1]
					// centerPos = {
					// 	x: startPos.x + 0.5,
					// 	y: startPos.y
					// }
					endPos = {
						x: startPos.x + 1,
						y: startPos.y
					}
				} else {
					startPos = coordinates[coordinatesLen - 2]
					// centerPos = coordinates[coordinatesLen - 1]
					endPos = coordinates[coordinatesLen - 1]
				}
				const style = currentLineData.style
				this.ctx.save()
				this.ctx.beginPath()
				this.ctx.setLineCap('round')
				// this.ctx.shadowBlur = 10;
				// this.ctx.shadowColor = 'rgb(0, 0, 0)';
				this.ctx.setGlobalAlpha(0.5)
				this.ctx.setStrokeStyle(style.color)
				this.ctx.setLineWidth(style.width)
				this.ctx.moveTo(startPos.x, startPos.y)
				this.ctx.lineTo(endPos.x, endPos.y)
				// const P1 = this.caculateBezier(startPos, endPos, centerPos)
				// this.ctx.moveTo(startPos.x, startPos.y)
				// this.ctx.quadraticCurveTo(P1.x, P1.y, endPos.x, endPos.y)
				this.ctx.stroke()
				this.ctx.restore();
				this.ctx.draw(true)
			},
			export () { //导出图片
				return new Promise((resolve, reject) => {
					this.drawArr = this.drawArr.map((item) => {
						item.selected = false;
						return item;
					});
					this.draw().then(() => {
						uni.canvasToTempFilePath({
							canvasId: 'first',
							success: (res) => {
								console.log(res.tempFilePath);
								resolve(res.tempFilePath);

							},
							fail: (e) => {
								reject(e);
							},
						}, this);
					});
				})
			},
			changColor(color) {
				const selected = this.drawArr.filter((item) => item.selected);
				if (selected.length > 0) {
					selected[0].color = color;
				}
				this.draw();
			},
			changeBgColor(color) {
				this.bgImage = '';
				this.bgColor = color;
				this.draw();
			},
			changeBgImage(url) {
				this.bgColor = '';
				this.bgImage = url;
				this.draw();
			},
			/**
			 * 计算二次贝塞尔曲线 控制点 P1
			 * 起点 P0(x0,y0)、控制点P1(x1, y1)、P2(x2, y2)、曲线上任意点B(x, y)
			 * 二次贝塞尔公式：B(t) = (1-t)²P0 + 2t(1-t)P1 + t²P2
			 * 代入坐标得：
			 * x = (1-t)²*x0 + 2t(1-t)*x1 + t²*x2
			 * y = (1-t)²*y0 + 2t(1-t)*y1 + t²*y2
			 */
			caculateBezier(P0, P2, B, t = 0.5) {
				const {
					x: x0,
					y: y0
				} = P0
				const {
					x: x2,
					y: y2
				} = P2
				const {
					x,
					y
				} = B
				let x1 = (x - (1 - t) * (1 - t) * x0 - t * t * x2) / (2 * t * (1 - t))
				let y1 = (y - (1 - t) * (1 - t) * y0 - t * t * y2) / (2 * t * (1 - t))
				return {
					x: x1,
					y: y1
				}
			}
		}
	}
</script>

<style lang="scss">
	.canvas {
		background: url('../../static/test.png') no-repeat;
		background-size: 100%;
	}
</style>
